using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AvaloniaDrawingPad.Models
{
    /// <summary>
    /// 表示整个绘图项目的数据
    /// </summary>
    public class ProjectData
    {
        public string Version { get; set; } = "1.0";
        public double CanvasWidth { get; set; }
        public double CanvasHeight { get; set; }
        public List<LayerData> Layers { get; set; } = new List<LayerData>();
        
        // 用于序列化为JSON
        public string ToJson()
        {
            var options = new JsonSerializerOptions
            {
                NumberHandling =
                    JsonNumberHandling.AllowReadingFromString |
                    JsonNumberHandling.WriteAsString,
                WriteIndented = true
            };
            return JsonSerializer.Serialize(this, options);
        }
        
        // 从JSON反序列化
        public static ProjectData? FromJson(string json)
        {
            try
            {
                var options = new JsonSerializerOptions
                {
                    NumberHandling =
                    JsonNumberHandling.AllowReadingFromString |
                    JsonNumberHandling.WriteAsString,
                    WriteIndented = true
                };
                return JsonSerializer.Deserialize<ProjectData>(json, options);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"反序列化失败: {ex.Message}");
                return null;
            }
        }
    }
    
    /// <summary>
    /// 表示单个图层的数据
    /// </summary>
    public class LayerData
    {
        public string Name { get; set; } = "";
        public bool IsVisible { get; set; } = true;
        public List<ShapeData> Shapes { get; set; } = new List<ShapeData>();
    }
    
    /// <summary>
    /// 图形数据的基类
    /// </summary>
    [JsonDerivedType(typeof(LineData), typeDiscriminator: "Line")]
    [JsonDerivedType(typeof(RectangleData), typeDiscriminator: "Rectangle")]
    [JsonDerivedType(typeof(EllipseData), typeDiscriminator: "Ellipse")]
    [JsonDerivedType(typeof(FreeDrawData), typeDiscriminator: "FreeDraw")]
    [JsonDerivedType(typeof(ImageData), typeDiscriminator: "Image")]
    public abstract class ShapeData
    {
        public string Type { get; set; } = "";
        public string StrokeColor { get; set; } = "#000000";
        public double StrokeThickness { get; set; } = 1.0;
        public string? FillColor { get; set; }
        
        // 从图形对象创建数据模型的工厂方法
        public static ShapeData? FromShape(Control element)
        {
            if (element is Line line)
            {
                return new LineData
                {
                    Type = "Line",
                    StrokeColor = ((ISolidColorBrush)line.Stroke).Color.ToString(),
                    StrokeThickness = line.StrokeThickness,
                    StartX = line.StartPoint.X,
                    StartY = line.StartPoint.Y,
                    EndX = line.EndPoint.X,
                    EndY = line.EndPoint.Y
                };
            }
            else if (element is Rectangle rect)
            {
                return new RectangleData
                {
                    Type = "Rectangle",
                    StrokeColor = rect.Stroke != null ? ((ISolidColorBrush)rect.Stroke).Color.ToString() : "#000000",
                    StrokeThickness = rect.StrokeThickness,
                    FillColor = rect.Fill != null ? ((ISolidColorBrush)rect.Fill).Color.ToString() : null,
                    X = Canvas.GetLeft(rect),
                    Y = Canvas.GetTop(rect),
                    Width = rect.Width,
                    Height = rect.Height
                };
            }
            else if (element is Ellipse ellipse)
            {
                return new EllipseData
                {
                    Type = "Ellipse",
                    StrokeColor = ellipse.Stroke != null ? ((ISolidColorBrush)ellipse.Stroke).Color.ToString() : "#000000",
                    StrokeThickness = ellipse.StrokeThickness,
                    FillColor = ellipse.Fill != null ? ((ISolidColorBrush)ellipse.Fill).Color.ToString() : null,
                    X = Canvas.GetLeft(ellipse),
                    Y = Canvas.GetTop(ellipse),
                    Width = ellipse.Width,
                    Height = ellipse.Height
                };
            }
            else if (element is Canvas canvas)
            {
                // 自由绘制的线条集合
                var freeDrawData = new FreeDrawData
                {
                    Type = "FreeDraw",
                    X = Canvas.GetLeft(canvas),
                    Y = Canvas.GetTop(canvas),
                    Width = canvas.Width,
                    Height = canvas.Height
                };
                
                foreach (var child in canvas.Children)
                {
                    if (child is Line childLine)
                    {
                        freeDrawData.Lines.Add(new FreeDrawLineData
                        {
                            StartX = childLine.StartPoint.X,
                            StartY = childLine.StartPoint.Y,
                            EndX = childLine.EndPoint.X,
                            EndY = childLine.EndPoint.Y,
                            StrokeColor = ((ISolidColorBrush)childLine.Stroke).Color.ToString(),
                            StrokeThickness = childLine.StrokeThickness
                        });
                    }
                }
                
                return freeDrawData;
            }
            else if (element is Image image)
            {
                if (image.Source is Bitmap bitmap)
                {
                    // 对于图片，保存相对路径和位置信息
                    return new ImageData
                    {
                        Type = "Image",
                        X = Canvas.GetLeft(image),
                        Y = Canvas.GetTop(image),
                        Width = image.Width,
                        Height = image.Height
                    };
                }
            }
            
            return null;
        }
        
        // 创建图形的抽象方法，由子类实现
        public abstract Control CreateShape();
    }
    
    public class LineData : ShapeData
    {
        public double StartX { get; set; }
        public double StartY { get; set; }
        public double EndX { get; set; }
        public double EndY { get; set; }
        
        public override Control CreateShape()
        {
            return new Line
            {
                StartPoint = new Point(StartX, StartY),
                EndPoint = new Point(EndX, EndY),
                Stroke = SolidColorBrush.Parse(StrokeColor),
                StrokeThickness = StrokeThickness,
                StrokeLineCap = PenLineCap.Round
            };
        }
    }
    
    public class RectangleData : ShapeData
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        
        public override Control CreateShape()
        {
            var rectangle = new Rectangle
            {
                Width = Width,
                Height = Height,
                Stroke = SolidColorBrush.Parse(StrokeColor),
                StrokeThickness = StrokeThickness
            };
            
            if (FillColor != null)
            {
                rectangle.Fill = SolidColorBrush.Parse(FillColor);
            }
            
            Canvas.SetLeft(rectangle, X);
            Canvas.SetTop(rectangle, Y);
            
            return rectangle;
        }
    }
    
    public class EllipseData : ShapeData
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        
        public override Control CreateShape()
        {
            var ellipse = new Ellipse
            {
                Width = Width,
                Height = Height,
                Stroke = SolidColorBrush.Parse(StrokeColor),
                StrokeThickness = StrokeThickness
            };
            
            if (FillColor != null)
            {
                ellipse.Fill = SolidColorBrush.Parse(FillColor);
            }
            
            Canvas.SetLeft(ellipse, X);
            Canvas.SetTop(ellipse, Y);
            
            return ellipse;
        }
    }
    
    public class FreeDrawLineData
    {
        public double StartX { get; set; }
        public double StartY { get; set; }
        public double EndX { get; set; }
        public double EndY { get; set; }
        public string StrokeColor { get; set; } = "#000000";
        public double StrokeThickness { get; set; } = 1.0;
    }
    
    public class FreeDrawData : ShapeData
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        public List<FreeDrawLineData> Lines { get; set; } = new List<FreeDrawLineData>();
        
        public override Control CreateShape()
        {
            var canvas = new Canvas
            {
                Width = Width,
                Height = Height,
                Background = Brushes.Transparent
            };
            
            Canvas.SetLeft(canvas, X);
            Canvas.SetTop(canvas, Y);
            
            foreach (var line in Lines)
            {
                var lineElement = new Line
                {
                    StartPoint = new Point(line.StartX, line.StartY),
                    EndPoint = new Point(line.EndX, line.EndY),
                    Stroke = SolidColorBrush.Parse(line.StrokeColor),
                    StrokeThickness = line.StrokeThickness,
                    StrokeLineCap = PenLineCap.Round
                };
                
                canvas.Children.Add(lineElement);
            }
            
            return canvas;
        }
    }
    
    public class ImageData : ShapeData
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        public string ImagePath { get; set; } = ""; // 图片文件相对路径
        public string Base64Data { get; set; } = ""; // 图片的Base64编码数据，用于内嵌图片
        
        // 我们需要重写这个方法，处理图片的特殊情况
        public override Control CreateShape()
        {
            var image = new Image
            {
                Width = Width,
                Height = Height,
                Stretch = Stretch.Uniform
            };
            
            Canvas.SetLeft(image, X);
            Canvas.SetTop(image, Y);
            
            // 这里我们会处理从Base64数据加载图片
            // 实际使用时，需要在ProjectManager中处理图片的加载
            
            return image;
        }
    }
} 